#ifndef accountmanager_utils_statement_h
#define accountmanager_utils_statement_h

#include <utils/utils_decl.h>

#include <utils/item.h>
#include <utils/item_list.h>
#include <utils/account.h>
#include <utils/core/list.h>
#include <utils/core/map.h>
#include <utils/core/vector.h>

#include <QDate>

namespace AccountManagerUtils {

//! Information about a collection of monthly bank statements
/*!
 *  Each monthly bank statement is only available in the context of the month and bank account it belongs to
 */
class _accountmanager_utils_decl Statement {
	friend class StatementCollection;
	friend class StatementLib;

public:
	~Statement();
	
	const QDate& month() const;
	const ItemList& items() const;

	Item::ValueType delta() const;
	Item::ValueType delta(const QDate& date) const;

protected:
	Statement();
	Statement(const Statement& rhs);
	Statement(const QDate& month, const ItemList& items);
	Statement& operator=(const Statement& rhs);

private:
	QDate month_;
	const ItemList* items_;
	ItemList items_dummy_;
};

//===========================================================
	
//! Information about a collection of monthly bank statements
/*!
 *  Each monthly bank statement is only available in the context of the month and bank account it belongs to
 */
class _accountmanager_utils_decl StatementCollection {
	friend class StatementLib;

public:
	StatementCollection(const StatementCollection& rhs);
	~StatementCollection();
	StatementCollection& operator=(const StatementCollection& rhs);

	bool add_item(const Item& item, bool allow_multiples = true);
	bool remove_item(const Item& item, bool remove_all = false);
	bool has_item(const Item& item) const;
	int item_count(const Item& item) const;
	
	QDate start_date() const;
	QDate end_date() const;

	Item::ValueType balance(const QDate& date) const;

	Statement statement(const QDate& month) const;

protected:
	StatementCollection( Item::ValueType first_balance = 0 );

private:
	typedef Map< QDate, ItemList > StatementMap;
	
private:
	StatementMap map_;
	QDate start_date_;
	QDate end_date_;
	Item::ValueType first_balance_;
};

//===========================================================

class _accountmanager_utils_decl StatementLib {

public:
	static StatementCollection* find_statement_collection(const Account& account);
	static Statement find_statement(const Account& account, const QDate& month);
	
	~StatementLib();

private:
	StatementLib();

	static StatementLib* instance();

	static StatementCollection* create_statement_collection(const Account& account, Item::ValueType first_balance);

private:
	typedef Map< const Account*, StatementCollection > AccountMap;

private:
	AccountMap map_;

	static StatementLib* instance_;
};

} // namespace AccountManagerUtils

#endif
